﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPMS.Commons.Configuration;
using SPMS.Utility;

namespace SPMS.Log.Configuration
{
    /// <summary>
    /// 抽象节点处理器
    /// </summary>
    /// <remarks></remarks>
    /// <history>
    /// [zanezeng]   2008-11-17 9:38    Created
    /// </history>
    public abstract class AbstractNodeHandler : IConfigurationNodeHandler<ParseContext>
    {
        #region ---IConfigurationNodeHandler<ParseContext>

        /// <summary>
        /// 根据指定的上下文处理指定的节点
        /// </summary>
        /// <param name="node">配置节点</param>
        /// <param name="context">解析上下文</param>
        /// <returns>根据配置信息创建的对象</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-13 13:21    Created
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 9:39    Created
        /// </history>
        public object Porcess( IConfigurationNode node, ParseContext context )
        {
            //判断节点是否为Null
            if (null == node)
            {
                //输出日志
                if (LoggingContext.MetaLog.IsTraceEnabled)
                {
                    LoggingContext.MetaLog.Trace( "配置节点为Null，忽略处理" );
                }

                //返回
                return null;
            }

            //输出日志
            if (LoggingContext.MetaLog.IsTraceEnabled)
            {
                LoggingContext.MetaLog.Trace( "使用解析器'{0}'解析配置节点'{1}'", this.GetType(), node );
            }

            //处理
            return this.ProcessInternal( node, context );
        }

        #endregion

        #region ---Protected Method

        /// <summary>
        /// 处理指定的节点
        /// </summary>
        /// <param name="node">配置节点</param>
        /// <param name="context">解析上下文</param>
        /// <returns>根据配置信息创建的对象</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 11:39    Created
        /// </history>
        protected abstract object ProcessInternal( IConfigurationNode node, ParseContext context );

        /// <summary>
        /// 获得处理指定节点的节点处理器
        /// </summary>
        /// <param name="node">需要处理的节点</param>
        /// <param name="context">解析上下文</param>
        /// <returns>节点处理器</returns>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]   2008-11-17 10:10    Created
        /// </history>
        protected IConfigurationNodeHandler<ParseContext> GetNodeHandler( IConfigurationNode node, ParseContext context )
        {
            //从解析上下文获得节点处理器
            IConfigurationNodeHandler<ParseContext> handler = context.GetNodeHandler( node );

            //判断是否为Null
            if (null == handler)
            {
                //输出日志
                if (LoggingContext.MetaLog.IsErrorEnabled)
                {
                    LoggingContext.MetaLog.Error( "没有找到节点{0}的节点处理器", node.Name );
                }

                //抛出异常
                throw new NotSupportedException( string.Format( Properties.Resources.MSG_TAG_NOTSUPPORTED, node.Name ) );
            }

            //返回节点处理器
            return handler;
        }

        /// <summary>
        /// 判断指定的节点是否包含指定的属性
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="attributeName">属性的名称</param>
        /// <returns>
        /// 	<c>true</c>：包含指定的属性<br/>
        /// 	<c>false</c>：不包含指定的属性
        /// </returns>
        /// <remarks></remarks>
        /// <exception cref="System.ArgumentNullException"><paramref name="node"/>为Null</exception>
        /// <history>
        /// [zanezeng]   2008-11-17 14:22    Created
        /// </history>
        protected bool HasAttribute( IConfigurationNode node, string attributeName )
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull( node, "node" );

            //返回
            return node.Attributes.ContainsKey( attributeName );
        }

        /// <summary>
        /// 获得指定节点的指定属性的值
        /// </summary>
        /// <param name="node">节点</param>
        /// <param name="attributeName">属性的名称</param>
        /// <param name="context">解析上下文</param>
        /// <returns>
        /// 如果指定的属性不存在，则返回Null。如果属性名称为<c>null</c>引用或者空字符串，则返回空字符串。
        /// </returns>
        /// <remarks></remarks>
        /// <exception cref="System.ArgumentNullException"><paramref name="node"/>为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]   2008-11-17 14:19    Created
        /// </history>
        protected string GetAttributeValue( IConfigurationNode node, string attributeName, ParseContext context )
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull( node, "node" );

            //判断属性名称是否为空引用或者为空字符串
            if (string.IsNullOrEmpty( attributeName ))
            {
                //如果属性名称为空引用或者空字符串，则返回空字符串
                return string.Empty;
            }

            //用于保存属性
            IConfigurationAttribute attribute;

            //尝试获得属性值
            if (!node.Attributes.TryGetValue( attributeName, out attribute ))
            {
                //如果属性值获得失败，则返回空字符串
                return string.Empty;
            }

            //判断获得的属性值是否为空引用
            if (null == attribute)
            {
                //如果获得的属性值为空引用，则返回空字符串
                return string.Empty;
            }

            //获得属性值
            string attributeValue = attribute.Value;

            //判断属性值是否为扩展变量名称
            if (null != attributeValue && attributeValue.StartsWith( PREFIX_EXTENDED_QUALIFIER ) && attributeValue.EndsWith( PREFIX_EXTENDED_QUALIFIER ))
            {
                //获得扩展扩展变量的名称
                attributeValue = attributeValue.Substring( 1, attributeValue.Length - 2 );

                //如果是扩展变量名称，则获得扩展变量
                attributeValue = context.VariableProvider.GetExtendedVariable( attributeValue );
            }

            //返回属性的值
            return StringUtility.Trim( attributeValue );
        }

        #endregion

        #region ---Field

        /// <summary>
        /// 扩展属性的限定符
        /// </summary>
        private const string PREFIX_EXTENDED_QUALIFIER = "%";

        #endregion
    }
}
